; NASM 汇编编译器为 bin 文件格式提供了额外的操作符 org
; 它的功能是指定程序被载入内存时的起始地址
; 一句话，就是为程序中所有的内部地址引用增加一个段内偏移值
; 引导程序可以看做是被加载到以 0 为基址的段，偏移为 0x7c00
org 0x7c00

jmp start			; 跳转到 start 标签处运行

start:
    xor ax, ax		; xor 指令与 and or 指令类似，两个操作数的每一对对应位都应用如下操作原则：
					; 如果两个位的值相同（同为 0 或同为 1），则结果位等于 0；否则结果位等于 1
					; xor ax, ax 等于 ax = 0
	mov ss, ax		; 栈段 ss = 0
	mov ds, ax		; 数据段 ds = 0
	mov es, ax		; 附加数据段 es = 0 

	; 功能：清屏
  	mov ah, 0x06    ; AH 功能号 = 0x06
	mov bh, 0x07	; 清屏属性
  	mov al, 0x00    ; AL = 上卷的行数（如果为0，表示全部）
  	mov cx, 0x0000  ; 窗口左上角(CL, CH)位置,即(0, 0)
  	mov dx, 0x184f  ; 窗口右下角(DL, DH)位置
                    ; VGA 文本模式中，一行只能容纳 80 个字节，共 25 行 ，
                	; 下标从 0 开始，所以 0x18 =24, 0x4f = 79
    int 0x10

	; 直接操作显存，显存地址：0xb8000
	; 两个字节为一组，buf[0]：要显示的字符；buf[1]：属性。0x07(黑底白字)
	mov ax, 0xb800
	mov gs, ax

	mov cx, 15		; 循环次数
	mov si, msg		; 要打印的数据
	call print

	jmp $	; 死循环. $ 表示程序当前位置

; 参数 si : 打印的数据起始地址
; 参数 cx : 打印的长度
print:
	push bx
	push si
	push ax
	
	; 循环将 si 中的数据搬到 gs:bx 中
	mov bx, 0
  s:mov al, [si]
  	mov byte [gs:bx], al
	inc si
  	inc bx
    mov byte [gs:bx], 0x07
  	inc bx
	loop s

	pop ax
	pop si
	pop bx
	ret


msg db "Welcome to KOS."
times 510-($-$$) db 0x00 	; $ 表示程序当前位置
							; $$ 指代本 section 的起始地址
							; 如果没有定义 section ，nasm 默认全部代码同为一个 section ，起始地址为 0
							; 该指令表示将当前位置到 510 字节处全部填充数据 0x00
db 0x55, 0xaa			 	; 主引导程序最后 2 个字节为 0x55, 0xaa
	